home *** CD-ROM | disk | FTP | other *** search
- * ========================================================================
- * pmatch.asm -- routines to emulate AmigaDOS 2.0 pattern matcher
- * ©1991 by Talin / Sylvan Technical Arts
- * ========================================================================
-
- ; register usage:
- ; d0 - scratch
- ; d1 - next opcode
- ; d2 - scratch
- ; d3 - IsWild
- ; d4 - stack limit
- ; d5 - 'all' flag
-
- ; a0 - scratch
- ; a1 - scratch
- ; a2 - pattern
- ; a3 - out
- ; a4 - outlimit
- ; a5 - start of opcode / save
-
- PMATCH_EOS equ $00
- PMATCH_NULL equ $10
- PMATCH_NOT equ $20
- PMATCH_WILD equ $30
- PMATCH_POUND equ $40
- PMATCH_CLASS equ $50
- PMATCH_NCLASS equ $60
- PMATCH_STRING equ $70
- PMATCH_CHOICE equ $80
- PMATCH_SKIP equ $90
-
- TICK equ 0x27
-
- xref ToEnglish
- far code
-
- patch_zeroop:
- moveq #0,d0 ; op size = 0
- patch_op: ; (a5 = loc, d1 = op, d0 = size )
- move.b d0,1(a5) ; loc[1] = size;
- lsr.w #8,d0 ; size >>= 8
- and.w #$0f,d0 ; size &= 0x0f
- or.w d1,d0 ; size += op
- move.b d0,(a5) ; loc[0] = size;
- rts
-
- opheader: move.l a3,d0 ; get output pointer
- addq.l #2,d0 ; add sizeof opcode
- sub.l a4,d0 ; subtract output limit
- bpl.s 1$ ; if over, then do nothing
- addq.w #2,a3 ; add sizeof opcode to output ptr
- 1$ rts ; return
-
- opdata: move.l a3,d2 ; get output pointer
- addq.l #1,d2 ; add sizeof byte
- sub.l a4,d2 ; subtract output limit
- bpl.s 1$ ; if over, then do nothing
- move.b d1,(a3)+ ; write data to output buffer
- 1$ rts ; return
-
- ppregs reg d2-d5/a2-a5
-
- xdef _PatternParse,PatternParse
-
- _PatternParse
- movem.l ppregs,-(sp) ; save registers
- move.l 32+4(sp),a2 ; get pattern address
- move.l 32+8(sp),a3 ; output buffer address
- move.l 32+12(sp),d0 ; size of output buffer
- bra.s pp1 ; go to C entry point
-
- PatternParse: ; (a2 = pattern, a3 = output buffer, d0 = limit)
- movem.l ppregs,-(sp) ; save registers
- pp1: move.l a3,a4 ; a4 <-- output buffer
- add.l d0,a4 ; add size of buffer to get out limit
- moveq #0,d3 ; set IsWild to zero
- moveq #-1,d5 ; set ALL to TRUE
-
- move.l sp,d4 ; d4 <-- stack pointer
- sub.l #400,d4 ; d4 <-- lower limit of stack
-
- bsr parse_pattern ; call recursive routine
- beq.s 1$ ; if failed, return normally
- move.b (a2),d0 ; get last character looked at
- bne.s 2$ ; if not zero, then failed.
-
- move.l a3,d0 ; get output pointer
- addq.l #2,d0 ; add 2
- sub.l a4,d0 ; subtract output limit
- bpl.s 2$ ; if over the end, then error
-
- moveq #0,d1 ; terminate buffer
- bsr opdata ; write out opcode
- bsr opdata ; and opdata
-
- move.l d3,d0 ; return IsWild
- movem.l (sp)+,ppregs ; restore registers
- rts ; return
-
- 2$ moveq #-1,d0 ; failed because of match error
- 1$ movem.l (sp)+,ppregs ; restore registers
- rts ; return
-
- ;---------- recursive pattern parsing subroutine
-
- parse_pattern:
-
- ;---------- save a5 on the stack, and check to make sure stack is not too deep
-
- move.l a5,-(sp) ; save starting point
- cmp.l sp,d4 ; compare stack ptr to stack limit
- bhs parse_fail ; if d4 is higher, then stack too deep
-
- *int parse_pattern(void)
- *{
-
- ;---------- a pattern or sub-pattern cannot start with a termination character
- ; such as ')' or '|'
-
- * /* pattern or pattern substring can't start with closing delimiter */
- *
- * if (*pat == '|' || *pat == ')')
- * { goto fail;
- * }
-
- move.b (a2),d0 ; d0 <-- current pattern character
-
- cmp.b #'|',d0 ; if '|' character (or)
- beq parse_fail ; goto fail
- cmp.b #')',d0 ; if close paren
- beq parse_fail ; goto fail
-
- ;---------- loop through the characters in the pattern, and take action based
- ; on the character seen.
-
- * while (*pat)
- * { char *start = out;
- * if (*pat == ')' || *pat == '|') return TRUE;
-
- loop1: move.b (a2),d0 ; d0 <-- *pat
- beq parse_succeed ; if character == '\0' then success
-
- move.l a3,a5 ; a5 <-- start of next output opcode
-
- cmp.b #'|',d0 ; if '|' character (or)
- beq parse_succeed ; end of pattern, pop a level
- cmp.b #')',d0 ; if close paren
- beq parse_succeed ; end of pattern, pop a level
-
- addq #1,a2 ; skip over character parsed
-
- ;---------- parse '#' (repeat) symbol
-
- * else if (*pat == '#')
- * { pat++;
- * opheader();
- * unless (parse_pattern()) goto fail;
- * patch_op(PMATCH_POUND,start,out-start-2);
-
- cmp.b #'#',d0 ; if '#' character (repeat)
- bne.s 10$ ; then
-
- bsr opheader ; reserve space for op header
- move.w d5,-(sp) ; save ALL flag
- moveq #0,d5 ; ALL = false
- bsr parse_pattern ; call parse_pattern recursively
- move.w (sp)+,d5 ; restore ALL flag
- tst.w d0 ; return
- beq parse_fail ; if failed, then also fail
-
- 4$ moveq #PMATCH_POUND,d1 ; op = PMATCH_POUND
-
- 5$ move.l a3,d0 ; d0 <-- out
- sub.l a5,d0 ; d0 <-- out - start
- subq.l #2,d0 ; d0 <-- out - start - 2 (size of op)
- bsr patch_op ; patch in the opcode.
-
- moveq #1,d3 ; IsWild = 1 (wildcards present)
- bra loop1 ; next character
-
- ;---------- parse '*' (star) symbol
-
- * else if (*pat == '*')
- * { pat++;
- * opheader();
- * opheader();
- * patch_op(PMATCH_WILD,start+2,0);
- * patch_op(PMATCH_POUND,start,out-start-2);
-
- 10$ cmp.b #'*',d0 ; if '*' character (star)
- bne.s 20$ ; then
-
- bsr opheader ; reserve space for POUND op header
- bsr opheader ; reserve space for WILDCARD op header
-
- addq #2,a5 ; start += 2
- moveq #PMATCH_WILD,d1 ; op = PMATCH_WILD
- bsr patch_zeroop ; patch op with no data field
- subq #2,a5 ; start -= 2
-
- ; moveq #PMATCH_POUND,d1 ; op = PMATCH
- bra.s 4$ ; do nstd_patch
-
- ;---------- parse '~' (negate) symbol
-
- * else if (*pat == '~')
- * { pat++;
- * opheader();
- * patch_op(PMATCH_NOT,start,0);
-
- 20$ cmp.b #'~',d0 ; if '~' character (negate)
- bne.s 30$ ; then
- moveq #PMATCH_NOT,d1 ; op = PMATCH_NOT
- bsr opheader ; reserve space for op header
- bsr patch_zeroop ; patch op with no data field
- moveq #1,d3 ; IsWild = 1 (wildcards present)
- bra.s loop1 ; get next character
-
- ;---------- parse '%' (null) symbol
-
- * else if (*pat == '%')
- * { pat++;
- * opheader();
- * patch_op(PMATCH_NULL,start,0);
-
- 30$ cmp.b #'%',d0 ; if '%' character (null)
- bne.s 40$ ; then
- moveq #PMATCH_NULL,d1 ; op = PMATCH_NULL
- bra std_patch ; finish up op
-
- ;---------- parse '?' (wildcard) symbol
-
- * else if (*pat == '?')
- * { pat++;
- * opheader();
- * patch_op(PMATCH_WILD,start,0);
-
- 40$ cmp.b #'?',d0 ; if '?' character (wildcard)
- bne.s 50$ ; then
- moveq #PMATCH_WILD,d1 ; op = PMATCH_WILD
- bra std_patch ; finish up op
-
- ;---------- parse '[' (class) symbol
-
- * else if (*pat == '[')
-
- 50$ cmp.b #'[',d0 ; if '[' character (class)
- bne.s 60$ ; then
-
- * { int op = PMATCH_CLASS;
-
- move.w #PMATCH_CLASS,-(sp) ; save PMATCH_CLASS on stack
-
- * pat++;
- * opheader();
-
- bsr opheader ; reserve space for op header
-
- * if (*pat == '~')
- * { pat++;
- * op = PMATCH_NCLASS;
- * }
-
- cmp.b #'~',(a2) ; if it's a negative class
- bne.s 51$ ; then
- addq #1,a2 ; skip over that character
- move.w #PMATCH_NCLASS,(sp) ; store PMATCH_NCLASS on stack
- 51$:
-
- * for (;;)
- * { if (*pat == '\0') goto fail;
- * if (*pat == ']') break;
- * if (*pat == TICK) pat++;
- * opdata(ToEnglish(*pat++));
- * }
-
- 52$ move.b (a2)+,d0 ; get next character
- beq.s 59$ ; if no closing bracket, fail
-
- cmp.b #']',d0 ; if it's a closing bracket
- beq.s 58$ ; then exit the loop
-
- cmp.b #TICK,d0 ; if it's a tick mark
- bne.s 55$ ; then
- move.b (a2)+,d0 ; bump pointer
-
- 55$ jsr ToEnglish ; convert to english
- move.w d0,d1 ; to d1
- bsr opdata ; write it out
- bra.s 52$ ; next character in char class
-
- * if (*pat != ']') return FALSE; (not needed now)
- * pat++;
- * patch_op(op,start,out-start-2);
-
- 58$ move.w (sp)+,d1 ; d1 <-- PMATCH_(N)CLASS
- bra 5$ ; do nstd_patch
-
- 59$ addq #2,sp ; clean up stack
- bra parse_fail ; return failure
-
- ;---------- parse '(' (group) symbol
-
- * else if (*pat == '(')
-
- 60$ cmp.b #'(',d0 ; if '(' character (group)
- bne 70$ ; then
-
- * { UBYTE *last_goto = NULL;
- * pat++;
-
- clr.l -(sp) ; push last_goto on stack (zero now)
- move.b (a2),d0 ; get next character, don't bump
-
- * for (;;)
- * { start = out;
-
- 61$ move.l a3,a5 ; save current out address
-
- * opheader();
- * unless (parse_pattern()) return FALSE;
-
- bsr opheader ; reserve space for opcode header
- bsr parse_pattern ; get sub-pattern
- beq.s 69$ ; if failed, then leave
-
- * patch_op(0, out, last_goto ? out - last_goto : 0);
-
- moveq #0,d0 ; size = 0
- tst.l (sp) ; if last_goto is nonzero
- beq.s 62$ ; then size is still zero
- move.l a3,d0 ; size = out
- sub.l (sp),d0 ; size = out - last_goto
-
- 62$ move.l a5,a0 ; save start in a0
- move.l a3,a5 ; write opcode to out, not start
- moveq #0,d1 ; opcode = 0 for now
- bsr patch_op ; patch in what we have
-
- move.l a0,a5 ; restore start ptr
-
- * last_goto = out;
-
- move.l a3,(sp) ; last_goto <-- out
-
- * opheader(); /* location of goto */
-
- bsr opheader ; reserve space for opcode
-
- * if (*pat == ')') break;
-
- move.b (a2)+,d0 ; get next character
- cmp.b #')',d0 ; if close paren
- beq.s 63$ ; break loop
-
- * if (*pat != '|') return FALSE;
-
- cmp.b #'|',d0 ; if not OR
- bne.s 69$ ; goto failure
-
- * patch_op(PMATCH_CHOICE,start,out-start-2);
-
- move.l a3,d0 ; d0 <-- out
- sub.l a5,d0 ; d0 <-- out - start
- subq.l #2,d0 ; d0 <-- out - start - 2
- moveq #PMATCH_CHOICE,d1 ; d1 = choice op
- bsr patch_op
-
- moveq #1,d3 ; IsWild = 1
- bra.s 61$ ; do next part of group
-
- * pat++;
- * }
- * patch_op(PMATCH_NULL,start,out-start-2);
-
- 63$
- move.l a3,d0 ; d0 <-- out
- sub.l a5,d0 ; d0 <-- out - start
- subq.l #2,d0 ; d0 <-- out - start - 2
- moveq #PMATCH_NULL,d1 ; d1 = null op
- bsr patch_op
-
- * pat++;
- * for (;;)
- * { int offset;
- * offset = (last_goto[0]<< 8) + last_goto[1];
-
- move.l (sp)+,a1 ; a1 <-- last_goto (also clean up stack)
-
- 64$ move.b (a1),d2 ; d2 <-- offset part 1
- lsl.w #8,d2 ; shifted over 8
- move.b 1(a1),d2 ; d2 <-- offset
-
- * patch_op(PMATCH_SKIP,last_goto,out-last_goto-2);
-
- move.l a1,a5 ; a3 <-- last_goto
- move.l a3,d0 ; d0 <-- out
- sub.l a1,d0 ; d0 <-- out - last_goto
- subq.l #2,d0 ; d0 <-- out - last_goto - 2
- moveq #PMATCH_SKIP,d1 ; d1 = skip op
- bsr patch_op ; patch in opcode
-
- * if (offset == 0) break;
- * last_goto -= offset;
-
- tst.w d2 ; if last in chain
- beq endloop ; then parse next op
-
- sub.w d2,a1 ; last_goto -= offset
- bra.s 64$ ; loop
-
- 69$ addq #4,sp ; clean up stack
- bra parse_fail
-
- ;---------- parse "'" (tick) symbol
-
- * { if (*pat == TICK) /* skip over tick character */
- * { pat++;
- * if (*pat=='\0') return FALSE; /* can't tick end of string */
- * }
- * opdata(PMATCH_STRING); /* STRING match op */
- * opdata(ToEnglish(*pat++)); /* character to match */
-
- 70$ cmp.b #TICK,d0 ; if "'" character (tick)
- bne.s 75$ ; then do
-
- move.b (a2)+,d0 ; get next character
- beq parse_fail ; can't tick the end of string
-
- ;---------- parse normal character
-
- 75$ moveq #PMATCH_STRING,d1 ; put out a PMATCH_STRING opcode
- bsr opdata ; write to output buffer
-
- bsr ToEnglish ; put out normal character
- move.w d0,d1 ; d0 <-- data to write
- bsr opdata ; write character to output buffer
-
- endloop: tst.w d5
- beq.s parse_succeed
-
- bra loop1 ; next character
-
- ;---------- finish up simple ops
-
- std_patch: bsr opheader ; reserve space for op header
- bsr patch_zeroop ; patch op with no data field
- moveq #1,d3 ; IsWild = 1 (wildcards present)
- tst.w d5 ; if ALL is true
- bne.s loop1 ; get next character
-
- ;---------- return success
-
- parse_succeed:
- move.l (sp)+,a5 ; restore starting point
- moveq #-1,d0 ; return failure code
- rts ; return
-
- ;---------- return failure
-
- parse_fail: move.l (sp)+,a5 ; restore starting point
- moveq #0,d0 ; return success code
- rts ; return
-
- ; register usage
- ; d0 - scratch
- ; d1 - current opcode
- ; d2 - length of op
- ; d4 - stack depth limit
- ; d5 - incomplete flag
-
- ; a0 - scratch
- ; a2 - name
- ; a3 - pattern
- ; a4 - pattern end
-
- xdef _PatternMatch,PatternMatch
-
- pmreg reg d2-d5/a2-a4
-
- _PatternMatch: ; (pat, name)
- movem.l pmreg,-(sp) ; save regs
- move.l 28+4(sp),a3 ; get pat
- move.l 28+8(sp),a2 ; get name
- bra.s pm1 ; go to C entry point
- PatternMatch: ; (pat: a3, name:a2)
- movem.l pmreg,-(sp) ; save regs
- pm1: move.l sp,d4 ; d4 <-- stack pointer
- sub.l #1200,d4 ; d4 <-- lower limit of stack
- moveq #0,d5 ; set incomplete to FALSE
- move.l a3,a4 ; a4 <-- pat
- add.l #1000,a4 ; a4 <-- pat end (lots for now)
- bsr interpret_pattern ; call recursive match routine
- movem.l (sp)+,pmreg ; restore registers
- rts
-
- * int interpret_pattern(char *pat,int plength,int incomplete_ok)
- *{ char *save = name,
- * *save2;
-
- interpret_pattern:
- movem.l a3,-(sp) ; save pattern address on stack
- movem.l a2,-(sp) ; save name address on stack
-
- cmp.l sp,d4 ; compare stack ptr to stack limit
- bhs match_fail ; if d4 is higher, then stack too deep
-
- * if (plength == 0) return (*name == '\0');
-
- cmp.l a3,a4 ; if we're at end of pattern
- bhi.s loop2 ; then
- tst.b (a2) ; if no more characters
- beq match_succeed ; then we succeeded
- bra match_fail ; else we failed
-
- * while (plength > 0)
-
- loop2: cmp.l a3,a4 ; while there's pattern left
- bls match_succeed
-
- * { WORD length,
- * code;
- * code = *pat & 0xf0;
- * length = ((pat[0] & 0x0f)<<8) + pat[1];
- * plength -= 2;
- * pat += 2;
-
- move.b (a3)+,d1 ; get code byte
- move.b d1,d2 ; move to length
- and.w #$f,d2 ; extract length
- lsl.w #8,d2 ; times 256
- move.b (a3)+,d2 ; get lower byte of length
-
- * switch (code) {
-
- lea jump_table(pc),a0
- lsr.w #2,d1
- and.w #$003c,d1
- move.l (a0,d1.w),a0
- jmp (a0)
-
- jump_table: dc.l match_eos ; 0x00
- dc.l match_null ; 0x10
- dc.l match_not ; 0x20
- dc.l match_wild ; 0x30
- dc.l match_pound ; 0x40
- dc.l match_class ; 0x50
- dc.l match_nclass ; 0x60
- dc.l match_string ; 0x70
- dc.l match_choice ; 0x80
- dc.l match_skip ; 0x90
- dc.l match_error ; 0xA0
- dc.l match_error ; 0xB0
- dc.l match_error ; 0xC0
- dc.l match_error ; 0xD0
- dc.l match_error ; 0xE0
- dc.l match_error ; 0xF0
-
- * case PMATCH_WILD:
- * if (*name == '\0') goto fail;
- * name++;
- * break;
-
- match_wild:
- tst.b (a2)+ ; can't wildcard end of string
- beq match_fail ; so that fails
- bra loop2 ; else it succeeds
-
- * case PMATCH_NULL:
- * break;
-
- match_null: bra loop2 ; do nothing at all
-
- * case PMATCH_EOS:
- * if (incomplete_ok || *name == '\0') return TRUE;
- * goto fail;
-
- match_eos: tst.w d5 ; if incomplete is OK
- bne match_succeed ; then we succeed
- tst.b (a2) ; if end of string
- beq match_succeed ; then we succeed
- bra match_fail ; else we fail
-
- * case PMATCH_NOT:
- * if (interpret_pattern(pat,plength,incomplete_ok) && *name == '\0') goto fail;
- * return TRUE;
- * break;
-
- match_not: bsr interpret_pattern ; call interpret_pattern
- beq match_succeed ; if test failed, then it succeeded
- tst.b (a2) ; if not end of string
- bne match_succeed ; then test also failed, but succeeded
- bra match_fail ; else we fail for real
-
- * case PMATCH_SKIP:
- * pat += length;
- * break;
-
- match_skip: add.w d2,a3 ; add length to pattern
- bra loop2 ; do next char
-
- * case PMATCH_CHOICE:
- * save2 = name;
- * if (interpret_pattern(pat,length + plength + 2,incomplete_ok)) return TRUE;
- * name = save2;
- * pat += length;
- * break;
-
- match_choice:
- add.w d2,a3 ; add length of op to pat
- move.l a3,-(sp) ; save next op addr on stack
- sub.w d2,a3 ; restore address to this op
- bsr interpret_pattern ; call interpret
- bne.s 10$ ; if succeeded, then ok
- move.l (sp)+,a3 ; restore next op addr from stack
- bra loop2 ; do next op
-
- 10$ addq #4,sp ; don't restore op addr from stack
- bra match_succeed ; and succeed
-
- * case PMATCH_NCLASS:
- * case PMATCH_CLASS:
- * plength -= length;
- * while (length--)
- * { if (length > 1 && pat[1] == '-')
- * { if (ToEnglish(*name) >= pat[0] &&
- * ToEnglish(*name) <= pat[2])
- * break;
- * else { pat += 3; length -= 2; }
- * }
- * else
- * { if (*pat == ToEnglish(*name)) break;
- * pat++;
- * }
- * }
- * pat += length + 1;
- * if (code == PMATCH_NCLASS)
- * { if (length >= 0) goto fail;
- * }
- * else
- * { if (length < 0) goto fail;
- * }
- * name++;
-
- match_class:
- match_nclass:
- move.b (a2),d0 ; get character in question
- jsr ToEnglish ; convert to UC english
-
- move.l a3,a1 ; a1 <-- pattern
- add.w d2,a1 ; a1 <-- next opcode (pattern + length)
-
- 20$ tst.w d2 ; check length
- beq.s 70$ ; if length is zero
- bmi.s 70$ ; or negative
-
- cmp.w #1,d2 ; if enough room for a range
- bls.s 50$ ; then see if there's a dash
- cmp.b #'-',1(a3) ; if it's a dash
- bne.s 50$ ; then check if character in range
-
- cmp.b 0(a3),d0 ; compare with first part of class
- blo.s 45$ ; if lower, then not in range
- cmp.b 2(a3),d0 ; compare with 2nd part of class
- bls.s 80$ ; if lower or same, then in class
-
- 45$ addq #3,a3 ; skip range definition
- subq #3,d2 ; subtract 3 from length
- bra.s 20$ ; check next member of class
-
- 50$ cmp.b (a3),d0 ; compare name byte with class byte
- beq.s 80$ ; if match, then go to "in class"
-
- 55$ addq #1,a3 ; next class character
- subq #1,d2 ; subtract 1 from length
- bra.s 20$ ; check next member of class
-
- ;---------- code to execute if character not in class
-
- 70$ cmp.b #PMATCH_CLASS/4,d1 ; if it's match class
- beq.s match_fail
- addq #1,a2 ; add 1 to name
- move.l a1,a3 ; next opode
- bra loop2
-
- ;---------- code to execute if character in class
-
- 80$ cmp.b #PMATCH_NCLASS/4,d1 ; if it's match nclass
- beq.s match_fail
- addq #1,a2 ; add 1 to name
- move.l a1,a3 ; next opode
- bra loop2
-
- * break;
- * case PMATCH_POUND:
- * for (;;)
- * { if (interpret_pattern(pat+length,plength-length,incomplete_ok)) return TRUE;
- * else if (!interpret_pattern(pat,length,TRUE)) goto fail;
- * }
-
- match_pound:
- move.w d2,-(sp) ; save length on stack
- add.w d2,a3 ; add op length to pat, giving op end
- bsr interpret_pattern ; interpret the pattern after this op
- bne.s 10$ ; if succeed, then return true
- move.w (sp),d2 ; get length of op again from stack
- movem.l d5/a4,-(sp) ; save pattern end and incomplete flg.
- move.l a3,a4 ; pattern end <-- pattern + pength
- sub.w d2,a3 ; pat <-- original pat
- moveq #-1,d5 ; set incomplete_ok to TRUE
- bsr interpret_pattern ; interpret op contents
- beq.s 20$ ; if no match then fail
- movem.l (sp)+,d5/a4 ; restore pattern end and incmplt.
- move.w (sp)+,d2 ; restore length from stack
- bra.s match_pound ; try another match.
-
- 10$ addq #2,sp ; clean up stack
- bra match_succeed ; and succeed
-
- 20$ lea 10(sp),sp ; clean up stack
- bra match_fail ; and fail
-
- * case PMATCH_STRING:
- * if (ToEnglish(*name++) != (length & 0x0ff)) goto fail;
- * break;
-
- match_string:
- move.b (a2)+,d0 ; get next character in name
- jsr ToEnglish ; convert to english upper case
- cmp.b d0,d2 ; if not the same as pat
- bne match_fail ; fail
- bra loop2 ; else next char
-
- * default:
- * Printf("Interpreter error!\n");
- * return FALSE;
-
- match_error:
- bra.s match_fail ; just fail
-
- * return MATCH;
-
- match_succeed:
- addq #4,sp ; don't restore name
- move.l (sp)+,a3 ; restore pat address from stack
- moveq #-1,d0 ; return success
- rts
-
-
- *fail:
- * name = save;
- * return FALSE;
-
- match_fail:
- move.l (sp)+,a2 ; restore name address from stack
- move.l (sp)+,a3 ; restore pat address from stack
- moveq #0,d0 ; return failure
- rts
-
-